<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Notebooks</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="GTK+ 2.0 Tutorial"
HREF="book1.html"><LINK
REL="UP"
TITLE="Container Widgets"
HREF="c1228.html"><LINK
REL="PREVIOUS"
TITLE="Toolbar"
HREF="x1404.html"><LINK
REL="NEXT"
TITLE="Menu Widget"
HREF="c1501.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>GTK+ 2.0 Tutorial</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x1404.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Container Widgets</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="c1501.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="SEC-NOTEBOOKS"
>Notebooks</A
></H1
><P
>The NoteBook Widget is a collection of "pages" that overlap each
other, each page contains different information with only one page
visible at a time. This widget has become more common lately in GUI
programming, and it is a good way to show blocks of similar
information that warrant separation in their display.</P
><P
>The first function call you will need to know, as you can probably
guess by now, is used to create a new notebook widget.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>GtkWidget *gtk_notebook_new( void );</PRE
></TD
></TR
></TABLE
><P
>Once the notebook has been created, there are a number of functions
that operate on the notebook widget. Let's look at them individually.</P
><P
>The first one we will look at is how to position the page indicators.
These page indicators or "tabs" as they are referred to, can be
positioned in four ways: top, bottom, left, or right.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void gtk_notebook_set_tab_pos( GtkNotebook     *notebook,
                               GtkPositionType  pos );</PRE
></TD
></TR
></TABLE
><P
>GtkPositionType will be one of the following, which are pretty self
explanatory:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>  GTK_POS_LEFT
  GTK_POS_RIGHT
  GTK_POS_TOP
  GTK_POS_BOTTOM</PRE
></TD
></TR
></TABLE
><P
><TT
CLASS="LITERAL"
>GTK_POS_TOP</TT
> is the default.</P
><P
>Next we will look at how to add pages to the notebook. There are three
ways to add pages to the NoteBook. Let's look at the first two
together as they are quite similar.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void gtk_notebook_append_page( GtkNotebook *notebook,
                               GtkWidget   *child,
                               GtkWidget   *tab_label );

void gtk_notebook_prepend_page( GtkNotebook *notebook,
                                GtkWidget   *child,
                                GtkWidget   *tab_label );</PRE
></TD
></TR
></TABLE
><P
>These functions add pages to the notebook by inserting them from the
back of the notebook (append), or the front of the notebook (prepend).
<TT
CLASS="LITERAL"
>child</TT
> is the widget that is placed within the notebook page, and
<TT
CLASS="LITERAL"
>tab_label</TT
> is the label for the page being added. The <TT
CLASS="LITERAL"
>child</TT
>
widget must be created separately, and is typically a set of options
setup witin one of the other container widgets, such as a table.</P
><P
>The final function for adding a page to the notebook contains all of
the properties of the previous two, but it allows you to specify what
position you want the page to be in the notebook.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void gtk_notebook_insert_page( GtkNotebook *notebook,
                               GtkWidget   *child,
                               GtkWidget   *tab_label,
                               gint         position );</PRE
></TD
></TR
></TABLE
><P
>The parameters are the same as _append_ and _prepend_ except it
contains an extra parameter, <TT
CLASS="LITERAL"
>position</TT
>.  This parameter is used to
specify what place this page will be inserted into the first page
having position zero.</P
><P
>Now that we know how to add a page, lets see how we can remove a page
from the notebook.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void gtk_notebook_remove_page( GtkNotebook *notebook,
                               gint         page_num );</PRE
></TD
></TR
></TABLE
><P
>This function takes the page specified by <TT
CLASS="LITERAL"
>page_num</TT
> and removes it
from the widget pointed to by <TT
CLASS="LITERAL"
>notebook</TT
>.</P
><P
>To find out what the current page is in a notebook use the function:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>gint gtk_notebook_get_current_page( GtkNotebook *notebook );</PRE
></TD
></TR
></TABLE
><P
>These next two functions are simple calls to move the notebook page
forward or backward. Simply provide the respective function call with
the notebook widget you wish to operate on. Note: When the NoteBook is
currently on the last page, and gtk_notebook_next_page() is called, the
notebook will wrap back to the first page. Likewise, if the NoteBook
is on the first page, and gtk_notebook_prev_page() is called, the
notebook will wrap to the last page.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void gtk_notebook_next_page( GtkNoteBook *notebook );

void gtk_notebook_prev_page( GtkNoteBook *notebook );</PRE
></TD
></TR
></TABLE
><P
>This next function sets the "active" page. If you wish the notebook to
be opened to page 5 for example, you would use this function.  Without
using this function, the notebook defaults to the first page.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void gtk_notebook_set_current_page( GtkNotebook *notebook,
                                    gint         page_num );</PRE
></TD
></TR
></TABLE
><P
>The next two functions add or remove the notebook page tabs and the
notebook border respectively.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void gtk_notebook_set_show_tabs( GtkNotebook *notebook,
                                 gboolean     show_tabs );

void gtk_notebook_set_show_border( GtkNotebook *notebook,
                                   gboolean     show_border );</PRE
></TD
></TR
></TABLE
><P
>The next function is useful when the you have a large number of pages,
and the tabs don't fit on the page. It allows the tabs to be scrolled
through using two arrow buttons.</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>void gtk_notebook_set_scrollable( GtkNotebook *notebook,
                                  gboolean     scrollable );</PRE
></TD
></TR
></TABLE
><P
><TT
CLASS="LITERAL"
>show_tabs</TT
>, <TT
CLASS="LITERAL"
>show_border</TT
> and <TT
CLASS="LITERAL"
>scrollable</TT
> can be either
TRUE or FALSE.</P
><P
>Now let's look at an example, it is expanded from the 
<TT
CLASS="FILENAME"
>testgtk.c</TT
> code
that comes with the GTK distribution. This small program creates a
window with a notebook and six buttons. The notebook contains 11
pages, added in three different ways, appended, inserted, and
prepended. The buttons allow you rotate the tab positions, add/remove
the tabs and border, remove a page, change pages in both a forward and
backward manner, and exit the program.</P
><P
><SPAN
CLASS="INLINEMEDIAOBJECT"
><IMG
SRC="images/notebook.png"></SPAN
></P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>&#13;#include &#60;stdio.h&#62;
#include &#60;gtk/gtk.h&#62;

/* This function rotates the position of the tabs */
static void rotate_book( GtkButton   *button,
                         GtkNotebook *notebook )
{
    gtk_notebook_set_tab_pos (notebook, (notebook-&#62;tab_pos + 1) % 4);
}

/* Add/Remove the page tabs and the borders */
static void tabsborder_book( GtkButton   *button,
                             GtkNotebook *notebook )
{
    gint tval = FALSE;
    gint bval = FALSE;
    if (notebook-&#62;show_tabs == 0)
	    tval = TRUE; 
    if (notebook-&#62;show_border == 0)
	    bval = TRUE;
    
    gtk_notebook_set_show_tabs (notebook, tval);
    gtk_notebook_set_show_border (notebook, bval);
}

/* Remove a page from the notebook */
static void remove_book( GtkButton   *button,
                         GtkNotebook *notebook )
{
    gint page;
    
    page = gtk_notebook_get_current_page (notebook);
    gtk_notebook_remove_page (notebook, page);
    /* Need to refresh the widget -- 
     This forces the widget to redraw itself. */
    gtk_widget_queue_draw (GTK_WIDGET (notebook));
}

static gboolean delete( GtkWidget *widget,
                        GtkWidget *event,
                        gpointer   data )
{
    gtk_main_quit ();
    return FALSE;
}

int main( int argc,
          char *argv[] )
{
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *table;
    GtkWidget *notebook;
    GtkWidget *frame;
    GtkWidget *label;
    GtkWidget *checkbutton;
    int i;
    char bufferf[32];
    char bufferl[32];
    
    gtk_init (&#38;argc, &#38;argv);
    
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    
    g_signal_connect (G_OBJECT (window), "delete_event",
	              G_CALLBACK (delete), NULL);
    
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);

    table = gtk_table_new (3, 6, FALSE);
    gtk_container_add (GTK_CONTAINER (window), table);
    
    /* Create a new notebook, place the position of the tabs */
    notebook = gtk_notebook_new ();
    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
    gtk_table_attach_defaults (GTK_TABLE (table), notebook, 0, 6, 0, 1);
    gtk_widget_show (notebook);
    
    /* Let's append a bunch of pages to the notebook */
    for (i = 0; i &#60; 5; i++) {
	sprintf(bufferf, "Append Frame %d", i + 1);
	sprintf(bufferl, "Page %d", i + 1);
	
	frame = gtk_frame_new (bufferf);
	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
	gtk_widget_set_size_request (frame, 100, 75);
	gtk_widget_show (frame);
	
	label = gtk_label_new (bufferf);
	gtk_container_add (GTK_CONTAINER (frame), label);
	gtk_widget_show (label);
	
	label = gtk_label_new (bufferl);
	gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
    }
      
    /* Now let's add a page to a specific spot */
    checkbutton = gtk_check_button_new_with_label ("Check me please!");
    gtk_widget_set_size_request (checkbutton, 100, 75);
    gtk_widget_show (checkbutton);
   
    label = gtk_label_new ("Add page");
    gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), checkbutton, label, 2);
    
    /* Now finally let's prepend pages to the notebook */
    for (i = 0; i &#60; 5; i++) {
	sprintf (bufferf, "Prepend Frame %d", i + 1);
	sprintf (bufferl, "PPage %d", i + 1);
	
	frame = gtk_frame_new (bufferf);
	gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
	gtk_widget_set_size_request (frame, 100, 75);
	gtk_widget_show (frame);
	
	label = gtk_label_new (bufferf);
	gtk_container_add (GTK_CONTAINER (frame), label);
	gtk_widget_show (label);
	
	label = gtk_label_new (bufferl);
	gtk_notebook_prepend_page (GTK_NOTEBOOK (notebook), frame, label);
    }
    
    /* Set what page to start at (page 4) */
    gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 3);

    /* Create a bunch of buttons */
    button = gtk_button_new_with_label ("close");
    g_signal_connect_swapped (G_OBJECT (button), "clicked",
			      G_CALLBACK (delete), NULL);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 0, 1, 1, 2);
    gtk_widget_show (button);
    
    button = gtk_button_new_with_label ("next page");
    g_signal_connect_swapped (G_OBJECT (button), "clicked",
			      G_CALLBACK (gtk_notebook_next_page),
			      G_OBJECT (notebook));
    gtk_table_attach_defaults (GTK_TABLE (table), button, 1, 2, 1, 2);
    gtk_widget_show (button);
    
    button = gtk_button_new_with_label ("prev page");
    g_signal_connect_swapped (G_OBJECT (button), "clicked",
			      G_CALLBACK (gtk_notebook_prev_page),
			      G_OBJECT (notebook));
    gtk_table_attach_defaults (GTK_TABLE (table), button, 2, 3, 1, 2);
    gtk_widget_show (button);
    
    button = gtk_button_new_with_label ("tab position");
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (rotate_book),
	              (gpointer) notebook);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 3, 4, 1, 2);
    gtk_widget_show (button);
    
    button = gtk_button_new_with_label ("tabs/border on/off");
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (tabsborder_book),
                      (gpointer) notebook);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 4, 5, 1, 2);
    gtk_widget_show (button);
    
    button = gtk_button_new_with_label ("remove page");
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (remove_book),
                      (gpointer) notebook);
    gtk_table_attach_defaults (GTK_TABLE (table), button, 5, 6, 1, 2);
    gtk_widget_show (button);
    
    gtk_widget_show (table);
    gtk_widget_show (window);
    
    gtk_main ();
    
    return 0;
}</PRE
></TD
></TR
></TABLE
><P
>I hope this helps you on your way with creating notebooks for your
GTK applications.</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="x1404.html"
ACCESSKEY="P"
>&#60;&#60;&#60; Previous</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="book1.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="c1501.html"
ACCESSKEY="N"
>Next &#62;&#62;&#62;</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Toolbar</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="c1228.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Menu Widget</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>